import json

from utils import log


def load(path):
    """
    本函数从一个文件中载入数据,并转换为dict或者list
    path 是保存文件的路径
    r 只能读 （带r的文件必须先存在）
    """
    with open(path, 'r', encoding='utf-8') as f:
        s = f.read()
        log('load', s)
        return json.loads(s)


def save(data, path):
    """
    本函数，把一个dict或者list写入文件
    w+ 可读可写 如果文件存在 则覆盖整个文件不存在则创建  //要close 之后才算完成写入
    """
    s = json.dumps(data, indent=2, ensure_ascii=False)
    with open(path, 'w+', encoding='utf-8') as f:
        log('save', path, s, data)
        f.write(s)


class Model(object):
    @classmethod
    def new(cls, form):
        m = cls(form)
        return m

    def __repr__(self):
        """
        这是magic function
        """
        classname = self.__class__.__name__
        # Python 字典(Dictionary) items() 函数以列表返回可遍历的(键, 值) 元组数组。
        properties = ['{}:({})'.format(k, v) for k, v in self.__dict__.items()]
        s = '\n'.join(properties)
        # 错误return '<{}\n{}>\n'.format(classname, s) 渲染html会编程标签
        return '< {}\n{} >\n'.format(classname, s)

    @classmethod
    def all(cls):
        """
        得到一个类的所有存储的实例
        """
        path = cls.db_path()
        models = load(path)
        ms = [cls.new(m) for m in models]
        return ms

    def save(self):
        """
        save用于把一个Model的实例保存到文件中;
        """
        # models = self.all()
        # log('models', models)
        #
        # models.append(self)
        # l = [m.__dict__ for m in models]
        # path = self.db_path()
        # save(l, path)
        """
        06models新增id属性
        """
        # 查找
        models = self.all()
        log('models', models)
        first_index = 0
        # 新增
        if self.__dict__.get('id') is None:
            if len(models) > 0:
                # 不是第一个数据
                self.id = models[-1].id + 1
            else:
                # 是第一个数据
                self.id = first_index
            models.append(self)
        # 更新
        else:
            index = -1
            for i, m in enumerate(models):
                if self.id == m.id:
                    id = i
                    break
            if index > -1:
                models[index] = self
        # 保存
        l = [m.__dict__ for m in models]
        path = self.db_path()
        save(l, path)

    @classmethod
    def db_path(cls):
        classname = cls.__name__
        path = '{}.txt'.format(classname)
        return path

    @classmethod
    def find_by(cls, **kwargs):
        """
        kwargs是只有一个元素的dict
        u = User.find_by(username='juran')
        """
        k, v = '', ''
        # key , value = 'username','juran'
        for key, value in kwargs.items():
            k, v = key, value
        all = cls.all()
        for m in all:
            if v == m.__dict__[k]:
                return m
        return None


class User(Model):
    # 场景1
    # 方法1__init__在__new__方法之后执行，__new__返回值作为__init__的参数
    # 方法2def __init__(self, form):
    #     self.username = form.get('username', '')
    #     self.password = form.get('password', '')

    # 场景2：Model有id属性
    def __init__(self, form):
        self.id = form.get('id', None)
        if self.id is not None:
            self.id = int(self.id)
        self.username = form.get('username', '')
        self.password = form.get('password', '')

    def validate_login(self):
        # 场景1：return self.username == 'juran' and self.password == '123'
        # 场景2:bug不支持用户名相同
        # u = User.find_by(username=self.username)
        # return u is not None and u.password == self.password

        # 场景3：支持用户名相同
        us = User.all()
        for u in us:
            if u.username == self.username and u.password == self.password:
                return True
        return False

    def validate_register(self):
        return len(self.username) > 2 and len(self.password) > 2


class Message(Model):
    # 重写 Model的new(self,form)≈ Model的new() + User(Model)的__init__(self.form) 结合
    # def new(self, form):
    #     self.author = form.get('author', '')
    #     self.message = form.get('message', '')
    def __init__(self, form):
        self.author = form.get('author', '')
        self.message = form.get('message', '')


"""
buffet
1.Message重写 Model的new(self,form)≈ Model的new() + User(Model)的__init__(self.form) 结合
2.
"""
